/* eslint-disable max-len */
import * as amis from 'amis';
import * as amisEditor from 'amis-editor';
import React from 'react';
import ReactDOM from 'react-dom';
import * as udpUI from '@cscec/udp-ui';
import * as antd from 'antd';
import { DatabaseOutlined } from '@ant-design/icons';
import { IOpts, wrapperRender } from './wrapperRender';
import { ToolBar, Tpl, Panel } from './Common';
import { formPluginGenerator } from './Form';
import { pagePluginGenerator } from './Page';
import { portalPluginGenerator } from './portal';
import { IPackages } from './base/interface';
import { asyncForEach } from './base/util';

export function isNumberType(fieldDbType: string) {
  return ['03', '04', '05', '06', '10'].includes(fieldDbType);
}

interface IColumn {
  controlType: string;
  fieldName: string;
  fieldNameChn: string;
  helpId: string;
  showFlg: 0 | 1;
  listShowFlg: 0 | 1;
  enumValue?: string;
  fieldDbType: string;
  decimalLen?: number;
  columnLen?: number;
  max?: number;
  min?: number;
}

export interface ITable {
  bizCode: string,
  tableName: string;
  tableNameChn: string;
  tableType: 0 | 1;
  bizColumnDesignQueryVoList: IColumn[];
}

const controlTypeToRendererName: Record<string, { type: string, scaffold: { [x: string]: any } } | undefined> = {
  Attachment: { type: 'udp-attachment', scaffold: { xtype: 'Attachment' } },
  BusinessHelp: { type: 'udp-business-help', scaffold: { xtype: 'BusinessHelp' } },
  MultipleBusinessHelp: { type: 'udp-business-help', scaffold: { xtype: 'BusinessHelp', multiple: true } },
  CommonHelp: { type: 'udp-common-help', scaffold: { xtype: 'CommonHelp' } },
  MultipleCustomerHelp: { type: 'udp-customer-help', scaffold: { xtype: 'CustomerHelp', multiple: true } },
  CustomerHelp: { type: 'udp-customer-help', scaffold: { xtype: 'CustomerHelp' } },
  CalcSubProjectHelp: { type: 'udp-calcsub-project-help', scaffold: { xtype: 'CalcSubProjectHelp' } },
  MultipleCalcSubProjectHelp: { type: 'udp-calcsub-project-help', scaffold: { xtype: 'CalcSubProjectHelp', multiple: true } },
  ProjectEngineeringHelp: { type: 'udp-project-engineering-help', scaffold: { xtype: 'ProjectEngineeringHelp' } },
  MultipleProjectEngineeringHelp: { type: 'udp-project-engineering-help', scaffold: { xtype: 'ProjectEngineeringHelp', multiple: true } },
  StandardPositionsHelp: { type: 'udp-standard-positions-help', scaffold: { xtype: 'StandardPositionsHelp' } },
  MultipleStandardPositionsHelp: { type: 'udp-standard-positions-help', scaffold: { xtype: 'StandardPositionsHelp', multiple: true } },
  Input: { type: 'udp-input', scaffold: { xtype: 'Input' } },
  InputNumber: { type: 'udp-input-number', scaffold: { xtype: 'InputNumber' } },
  Password: { type: 'udp-input-password', scaffold: { xtype: 'Password' } },
  TextArea: { type: 'udp-textarea', scaffold: { xtype: 'TextArea' } },
  MultipleSelect: { type: 'udp-select', scaffold: { xtype: 'Select', multiple: true } },
  Select: { type: 'udp-select', scaffold: { xtype: 'Select' } },
  SingleHelp: { type: 'udp-common-help', scaffold: { xtype: 'SingleHelp', multiple: false } },
  MultipleHelp: { type: 'udp-common-help', scaffold: { xtype: 'MultipleHelp', multiple: true } },
  ProjectHelp: { type: 'udp-project-help', scaffold: { xtype: 'ProjectHelp', multiple: false } },
  MultipleProjectHelp: { type: 'udp-project-help', scaffold: { xtype: 'ProjectHelp', multiple: true } },
  UserHelp: { type: 'udp-user-help', scaffold: { xtype: 'UserHelp' } },
  MultipleUserHelp: { type: 'udp-user-help', scaffold: { xtype: 'UserHelp', multiple: true } },
  OrgHelp: { type: 'udp-org-help', scaffold: { xtype: 'OrgHelp' } },
  MultipleOrgHelp: { type: 'udp-org-help', scaffold: { xtype: 'OrgHelp', multiple: true } },
  DeptHelp: { type: 'udp-dept-help', scaffold: { xtype: 'DeptHelp' } },
  MultipleDeptHelp: { type: 'udp-dept-help', scaffold: { xtype: 'DeptHelp', multiple: true } },
  StaticDicHelp: { type: 'udp-static-dic-help', scaffold: { xtype: 'StaticDicHelp' } },
  MultipleStaticDicHelp: { type: 'udp-static-dic-help', scaffold: { xtype: 'StaticDicHelp', multiple: true } },
  CustomerBusinessHelp: { type: 'udp-customer-business-help', scaffold: { xtype: 'CustomerBusinessHelp' } },
  MultipleCustomerBusinessHelp: { type: 'udp-customer-business-help', scaffold: { xtype: 'CustomerBusinessHelp', multiple: true } },

  HelpSelect:{type: 'udp-common-help', scaffold: { xtype: 'SingleHelp', multiple: false, modal: false, loadByFocus: true }},
  MultipleHelpSelect:{type: 'udp-common-help', scaffold: { xtype: 'MultipleHelp', multiple: true, modal: false, loadByFocus: true }},
  
  StaticDicHelpSelect:{type: 'udp-static-dic-help', scaffold: { xtype: 'StaticDicHelp', multiple: false, modal: false, loadByFocus: true }},
  MultipleStaticDicHelpSelect:{type: 'udp-static-dic-help', scaffold: { xtype: 'StaticDicHelp', multiple: true, modal: false, loadByFocus: true }},

  ProjectPositionsHelp: { type: 'udp-project-positions-help', scaffold: { xtype: 'ProjectPositionsHelp', multiple: false } },
  MultipleProjectPositionsHelp: { type: 'udp-project-positions-help', scaffold: { xtype: 'ProjectPositionsHelp', multiple: true } },

  EnterprisePositionsHelp: { type: 'udp-enterprise-positions-help', scaffold: { xtype: 'EnterprisePositionsHelp', multiple: false } },
  MultipleEnterprisePositionsHelp: { type: 'udp-enterprise-positions-help', scaffold: { xtype: 'EnterprisePositionsHelp', multiple: true } },

  ProjectUserHelp: { type: 'udp-project-user-help', scaffold: { xtype: 'ProjectUserHelp', multiple: false } },
  MultipleProjectUserHelp: { type: 'udp-project-user-help', scaffold: { xtype: 'ProjectUserHelp', multiple: true } },

  CheckboxGroup: { type: 'udp-checkbox-group', scaffold: { xtype: 'CheckboxGroup' } },
  RadioGroup: { type: 'udp-radio-group', scaffold: { xtype: 'RadioGroup' } },
  DatePicker: { type: 'udp-date-picker', scaffold: { xtype: 'DatePicker' } },
  DateTimePicker: { type: 'udp-date-picker', scaffold: { xtype: 'DateTimePicker', showTime: true } },
  RangePicker: { type: 'udp-daterange-picker', scaffold: { xtype: 'RangePicker' } },
  Switch: { type: 'udp-switch', scaffold: { xtype: 'Switch' } },
  HtmlEditor: { type: 'udp-html-editor', scaffold: { xtype: 'HtmlEditor' } },
};

function getControlType(field: IColumn) {
  // console.log('[debug], field: ', field.controlType, field.fieldNameChn, field.helpId);
  const { controlType } = field;
  const defaultRender = controlTypeToRendererName[controlType];
  if (!defaultRender) {
    console.error(`字段${field.fieldNameChn}(${field.fieldName})的控件类型${controlType}未找到对应的渲染器`);
  }
  const base = udpUI.udp.deepCopy({ type: 'input-text', scaffold: {}, ...defaultRender });
  if (base.type === 'udp-common-help') {
    base.scaffold.helpId = field.helpId;
  }

  if (base.type?.endsWith?.('-help')) {
    base.scaffold.nameField = `${field.fieldName}EXName`;
  }
  if (isNumberType(field.fieldDbType)) {
    if (Object.prototype.hasOwnProperty.call(field, 'decimalLen')) {
      base.scaffold.precision = field.decimalLen;
    } else {
      base.scaffold.precision = field.fieldDbType === '06' ? 2 : 0;
    }
    if (Object.prototype.hasOwnProperty.call(field, 'max')) {
      base.scaffold.max = field.max;
    }
    if (Object.prototype.hasOwnProperty.call(field, 'min')) {
      base.scaffold.min = field.min;
    }
  } else if (Object.prototype.hasOwnProperty.call(field, 'columnLen')) {
    base.scaffold.maxLength = field.columnLen;
  }
  if (['checkboxes', 'radios', 'select', 'udp-checkbox-group', 'udp-radio-group', 'udp-select'].includes(base.type)) {
    base.scaffold.options = field.enumValue ? field.enumValue.split(';').map((item) => {
      const vl = item.split('|');
      return { value: (isNumberType(field.fieldDbType) ? Number(vl[0]) : vl[0]), label: vl[1] };
    }) : [];
  }
  return base;
}

//创建字段插件
function createColumnPulgin(field: IColumn, table: ITable, designType: string = '') {
  const { BasePlugin } = amisEditor;
  const { fieldName, fieldNameChn } = field;
  const { type, scaffold } = getControlType(field);
  return class extends BasePlugin {
    // 这里要跟对应的渲染器名字对应上
    // 注册渲染器的时候会要求指定渲染器名字
    rendererName = type;

    // 暂时只支持这个，配置后会开启代码编辑器
    $schema = '/schemas/UnkownSchema.json';

    // 用来配置名称和描述
    name = `${fieldNameChn}(${fieldName})`;

    icon = <DatabaseOutlined />;

    description = `${type}, 自定义字段组件,仅可以被拖入对应主表/明细表表单中`;

    // tag，决定会在哪个分组下面显示的
    tags = [`${table.tableNameChn}[${table.tableName}] `];

    // 拖入组件里面时的初始数据
    scaffold = {
      type,
      name: fieldName,
      table: table.tableName,
      label: fieldNameChn,
      ...scaffold,
      dragType: 'specified-field', //拖动时校验的类型, 覆盖默认的
    };

    panelJustify = true;

    notRenderFormZone = true;

    isFormItem = true;

    type = 'data-plugin';

    // 用来生成预览图的
    previewSchema = this.scaffold;

    getRendererInfo(context) {
      const info: any = super.getRendererInfo(context);
      if (info && designType === 'extension' && context.schema.name && context.schema.name.indexOf('user_ext_') !== 0) {
        info.removable = false;
      }
      return info;
    }
  };
}
//创建特定表格/表单插件
function createTablePlugin(table: ITable, designType: string = '') {
  const { BasePlugin } = amisEditor;
  const { tableName, tableNameChn, bizCode, tableType } = table;
  const type = (tableType === 0 ? 'form' : 'table');  //主表用表单形式展现，明细表用表格形式展现
  return class extends BasePlugin {
    // 这里要跟对应的渲染器名字对应上
    // 注册渲染器的时候会要求指定渲染器名字
    rendererName = type;
    

    // 暂时只支持这个，配置后会开启代码编辑器
    $schema = '/schemas/UnkownSchema.json';

    // 用来配置名称和描述
    name = `${tableNameChn}(${tableName})`;
    description = tableType == 0 ? '主表form, 仅可拖入主表字段' : '明细表table,仅可以拖入对应明细表字段';
    icon = <DatabaseOutlined />;

    // tag，决定会在哪个分组下面显示的
    tags = [`自定义表格`];

    // 拖入组件里面时的初始数据
    scaffold = tableType === 0 ? 
    //主表
    {
      id: `${bizCode}_${tableName}`,
      title: tableNameChn,
      type,
      name: tableName,
      table: tableName,
      wrapWithPanel: false,
      mode: 'horizontal',
      dragType: `specified-${type}`, //拖动时校验的类型, specified-form
      body: [],
    }:{
      //明细表
      id: `${bizCode}_${tableName}`,
      title: tableNameChn,
      type,
      columnsTogglable: false,
      columns: [],
      tableProps: {
        showRowNumber: {
          editOptions: {}
        },
        busKey: 'id'
      },

      dragType: `specified-${type}`, //拖动时校验的类型, specified-table
      name: tableName,
      table: tableName,
      label: tableNameChn,
    };

    panelJustify = true;

    notRenderFormZone = true;

    type = 'specified-table-plugin';

    // 用来生成预览图的
    previewSchema = this.scaffold;

    getRendererInfo(context) {
      // console.log(1111);
      const info: any = super.getRendererInfo(context);
      // https://aisuda.bce.baidu.com/amis/zh-CN/docs/extend/editor#%E6%B3%A8%E5%86%8C%E6%B8%B2%E6%9F%93%E5%99%A8%E4%BF%A1%E6%81%AF
    }
  };
}

const global = window as any;

// 公共依赖包传入用户自定义组件库
const commonPackages: IPackages = {
  amis, amisEditor, React, ReactDOM, antd, udpUI,
};

// 注册全局组件到window
function initPackages(packages: IPackages) {
  Object.keys(packages).forEach((packageName) => {
    if (Object.prototype.hasOwnProperty.call(packages, 'packageName')) {
      global[packageName] = packages[packageName];
    }
  });
}

function loadWindowPlugins(remotePlugins: any[], key: string, isDesign: boolean) {
  const getAmisComponents = udpUI.udp.isFunction(global[key]?.default) ? global[key]?.default : global[key]?.getAmisComponents;
  if (getAmisComponents) {
    const plugins = getAmisComponents?.((component: any, options: IOpts) => wrapperRender(component, {
      ...options, groupType: 'remote', isPlugin: isDesign, isBaseComponent: false,
    }), commonPackages);

    // 组件包
    if (udpUI.udp.isArray(plugins)) {
      plugins?.forEach(({ plugin }: any) => {
        if (plugin && plugin !== udpUI.emptyFn) {
          remotePlugins.push(plugin);
        }
      });
    } else if (plugins?.plugin) {
      // 单个组件
      if (plugins.plugin !== udpUI.emptyFn) {
        remotePlugins.push(plugins.plugin);
      }
    }
  }
}

/**
 * 加载组件市场资源包
 * @param resource {组件id: 组件}
 */
export async function loadResource(resource: { [x: string]: { name: string, url: string }; } | undefined, isDesign: boolean) {
  const keys = Object.keys(resource || {});
  const remotePlugins: any[] = [];
  if (!resource || !keys.length) {
    return remotePlugins;
  }
  // 用户自定义组件库通过umd方式引入，依赖包通过window对象传入，保证一致性
  initPackages(commonPackages);
  await asyncForEach(keys, async (key: string) => {
    const { name, url } = resource[key];
    if (!global[name]) {
      try {
        const res: any = await udpUI.udp.request.get({ url, skipError: true });
        await new Promise((resolve) => {
          udpUI.loadScriptContent(res, resolve);
        });
      } catch (e) {
        console.log(e);
      }
    }
    loadWindowPlugins(remotePlugins, name, isDesign);
  });
  return remotePlugins;
}

/**
 * 动态导入资源包
 * @param resource
 * @param manager
 * @param isDesign
 */
export async function buildRenderers(resource: {
  [x: string]: { name: string; url: string; };
} | undefined, manager: any) {
  if (!resource) { return; }
  const marketPlugins = await loadResource(resource, true);
  marketPlugins.forEach((Plugin) => {
    if (!Plugin || manager.plugins.some((p: any) => p?.name === Plugin.prototype.name)) {
      return;
    }
    const newPlugin = new Plugin(manager); // 进行一次实例化
    newPlugin.order = newPlugin.order ?? 0;
    manager.plugins.push(newPlugin);
    // 重新排序
    manager.plugins.sort((a: any, b: any) => a.order! - b.order!); // 按order排序【升序】
    manager.buildRenderers();
  });
}

// 获取portal组件
export function getPortalPlugins(isDesign: boolean) {
  const plugins: any[] = [Tpl];
  portalPluginGenerator((component: any, options: IOpts) => wrapperRender(component, {
    ...options, group: '门户组件', groupType: 'portal', isPlugin: isDesign, isBaseComponent: false,
  }), commonPackages).forEach(({ plugin }: any) => {
    if (plugin && plugin !== udpUI.emptyFn) {
      plugins.push(plugin);
    }
  });
  return plugins;
}

// 获取系统自定义组件
export function getSystemCustomPlugins(isDesign: boolean = true, designType: string = '') {
  //返回Tool, Panel, ListPage, DetailPage, Form各个字段的插件
  const plugins = [ToolBar, Panel];
  
  [pagePluginGenerator, formPluginGenerator].forEach((pluginGenerator) => {
    pluginGenerator((component: any, options: IOpts) => wrapperRender(component, { ...options, isPlugin: isDesign, designType }), commonPackages).forEach(({ plugin }: any) => {
      if (plugin && plugin !== udpUI.emptyFn) {
        plugins.push(plugin);
      }
    });
  });

  return plugins;
}

// 获取字段元素组件
export function getFieldPulgins(tables: ITable[], designType?: string) {
  const plugins: any[] = [];

  tables.forEach((table: any) => {
    table.bizColumnDesignQueryVoList.forEach((column: IColumn) => {
      if (column.showFlg) {
        plugins.push(createColumnPulgin(column, table, designType));
      }
    });
  });

  return plugins;
}

// 获取主表/明细表插件
export function getTablePlugins(tables: ITable[], designType?: string) {
  const plugins: any[] = [];
  tables.forEach((table: any) => {
    plugins.push(createTablePlugin(table, designType));
  });
  return plugins;
}


export function getFormItemProps(field: IColumn, table: ITable) {
  const { type, scaffold } = getControlType(field);
  return {
    label: field.fieldNameChn,
    name: field.fieldName,
    type,
    table: table.tableName,
    ...scaffold,
  };
}
